# -*- coding: utf-8 -*-
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
from __future__ import annotations

from typing import MutableMapping, MutableSequence

from google.protobuf import timestamp_pb2  # type: ignore
import proto  # type: ignore

from grafeas.grafeas_v1.types import common, cvss, package
from grafeas.grafeas_v1.types import severity as g_severity
from grafeas.grafeas_v1.types import vex

__protobuf__ = proto.module(
    package="grafeas.v1",
    manifest={
        "VulnerabilityNote",
        "VulnerabilityOccurrence",
    },
)


class VulnerabilityNote(proto.Message):
    r"""A security vulnerability that can be found in resources.

    Attributes:
        cvss_score (float):
            The CVSS score of this vulnerability. CVSS
            score is on a scale of 0 - 10 where 0 indicates
            low severity and 10 indicates high severity.
        severity (grafeas.grafeas_v1.types.Severity):
            The note provider assigned severity of this
            vulnerability.
        details (MutableSequence[grafeas.grafeas_v1.types.VulnerabilityNote.Detail]):
            Details of all known distros and packages
            affected by this vulnerability.
        cvss_v3 (grafeas.grafeas_v1.types.CVSSv3):
            The full description of the CVSSv3 for this
            vulnerability.
        windows_details (MutableSequence[grafeas.grafeas_v1.types.VulnerabilityNote.WindowsDetail]):
            Windows details get their own format because
            the information format and model don't match a
            normal detail. Specifically Windows updates are
            done as patches, thus Windows vulnerabilities
            really are a missing package, rather than a
            package being at an incorrect version.
        source_update_time (google.protobuf.timestamp_pb2.Timestamp):
            The time this information was last changed at
            the source. This is an upstream timestamp from
            the underlying information source - e.g. Ubuntu
            security tracker.
        cvss_version (grafeas.grafeas_v1.types.CVSSVersion):
            CVSS version used to populate cvss_score and severity.
        cvss_v2 (grafeas.grafeas_v1.types.CVSS):
            The full description of the v2 CVSS for this
            vulnerability.
    """

    class Detail(proto.Message):
        r"""A detail for a distro and package affected by this
        vulnerability and its associated fix (if one is available).

        Attributes:
            severity_name (str):
                The distro assigned severity of this
                vulnerability.
            description (str):
                A vendor-specific description of this
                vulnerability.
            package_type (str):
                The type of package; whether native or non
                native (e.g., ruby gems, node.js packages,
                etc.).
            affected_cpe_uri (str):
                Required. The `CPE
                URI <https://cpe.mitre.org/specification/>`__ this
                vulnerability affects.
            affected_package (str):
                Required. The package this vulnerability
                affects.
            affected_version_start (grafeas.grafeas_v1.types.Version):
                The version number at the start of an interval in which this
                vulnerability exists. A vulnerability can affect a package
                between version numbers that are disjoint sets of intervals
                (example: [1.0.0-1.1.0], [2.4.6-2.4.8] and [4.5.6-4.6.8])
                each of which will be represented in its own Detail. If a
                specific affected version is provided by a vulnerability
                database, affected_version_start and affected_version_end
                will be the same in that Detail.
            affected_version_end (grafeas.grafeas_v1.types.Version):
                The version number at the end of an interval in which this
                vulnerability exists. A vulnerability can affect a package
                between version numbers that are disjoint sets of intervals
                (example: [1.0.0-1.1.0], [2.4.6-2.4.8] and [4.5.6-4.6.8])
                each of which will be represented in its own Detail. If a
                specific affected version is provided by a vulnerability
                database, affected_version_start and affected_version_end
                will be the same in that Detail.
            fixed_cpe_uri (str):
                The distro recommended `CPE
                URI <https://cpe.mitre.org/specification/>`__ to update to
                that contains a fix for this vulnerability. It is possible
                for this to be different from the affected_cpe_uri.
            fixed_package (str):
                The distro recommended package to update to that contains a
                fix for this vulnerability. It is possible for this to be
                different from the affected_package.
            fixed_version (grafeas.grafeas_v1.types.Version):
                The distro recommended version to update to
                that contains a fix for this vulnerability.
                Setting this to VersionKind.MAXIMUM means no
                such version is yet available.
            is_obsolete (bool):
                Whether this detail is obsolete. Occurrences
                are expected not to point to obsolete details.
            source_update_time (google.protobuf.timestamp_pb2.Timestamp):
                The time this information was last changed at
                the source. This is an upstream timestamp from
                the underlying information source - e.g. Ubuntu
                security tracker.
            source (str):
                The source from which the information in this
                Detail was obtained.
            vendor (str):
                The name of the vendor of the product.
        """

        severity_name: str = proto.Field(
            proto.STRING,
            number=1,
        )
        description: str = proto.Field(
            proto.STRING,
            number=2,
        )
        package_type: str = proto.Field(
            proto.STRING,
            number=3,
        )
        affected_cpe_uri: str = proto.Field(
            proto.STRING,
            number=4,
        )
        affected_package: str = proto.Field(
            proto.STRING,
            number=5,
        )
        affected_version_start: package.Version = proto.Field(
            proto.MESSAGE,
            number=6,
            message=package.Version,
        )
        affected_version_end: package.Version = proto.Field(
            proto.MESSAGE,
            number=7,
            message=package.Version,
        )
        fixed_cpe_uri: str = proto.Field(
            proto.STRING,
            number=8,
        )
        fixed_package: str = proto.Field(
            proto.STRING,
            number=9,
        )
        fixed_version: package.Version = proto.Field(
            proto.MESSAGE,
            number=10,
            message=package.Version,
        )
        is_obsolete: bool = proto.Field(
            proto.BOOL,
            number=11,
        )
        source_update_time: timestamp_pb2.Timestamp = proto.Field(
            proto.MESSAGE,
            number=12,
            message=timestamp_pb2.Timestamp,
        )
        source: str = proto.Field(
            proto.STRING,
            number=13,
        )
        vendor: str = proto.Field(
            proto.STRING,
            number=14,
        )

    class WindowsDetail(proto.Message):
        r"""

        Attributes:
            cpe_uri (str):
                Required. The `CPE
                URI <https://cpe.mitre.org/specification/>`__ this
                vulnerability affects.
            name (str):
                Required. The name of this vulnerability.
            description (str):
                The description of this vulnerability.
            fixing_kbs (MutableSequence[grafeas.grafeas_v1.types.VulnerabilityNote.WindowsDetail.KnowledgeBase]):
                Required. The names of the KBs which have
                hotfixes to mitigate this vulnerability. Note
                that there may be multiple hotfixes (and thus
                multiple KBs) that mitigate a given
                vulnerability. Currently any listed KBs presence
                is considered a fix.
        """

        class KnowledgeBase(proto.Message):
            r"""

            Attributes:
                name (str):
                    The KB name (generally of the form KB[0-9]+ (e.g.,
                    KB123456)).
                url (str):
                    A link to the KB in the [Windows update catalog]
                    (https://www.catalog.update.microsoft.com/).
            """

            name: str = proto.Field(
                proto.STRING,
                number=1,
            )
            url: str = proto.Field(
                proto.STRING,
                number=2,
            )

        cpe_uri: str = proto.Field(
            proto.STRING,
            number=1,
        )
        name: str = proto.Field(
            proto.STRING,
            number=2,
        )
        description: str = proto.Field(
            proto.STRING,
            number=3,
        )
        fixing_kbs: MutableSequence[
            "VulnerabilityNote.WindowsDetail.KnowledgeBase"
        ] = proto.RepeatedField(
            proto.MESSAGE,
            number=4,
            message="VulnerabilityNote.WindowsDetail.KnowledgeBase",
        )

    cvss_score: float = proto.Field(
        proto.FLOAT,
        number=1,
    )
    severity: g_severity.Severity = proto.Field(
        proto.ENUM,
        number=2,
        enum=g_severity.Severity,
    )
    details: MutableSequence[Detail] = proto.RepeatedField(
        proto.MESSAGE,
        number=3,
        message=Detail,
    )
    cvss_v3: cvss.CVSSv3 = proto.Field(
        proto.MESSAGE,
        number=4,
        message=cvss.CVSSv3,
    )
    windows_details: MutableSequence[WindowsDetail] = proto.RepeatedField(
        proto.MESSAGE,
        number=5,
        message=WindowsDetail,
    )
    source_update_time: timestamp_pb2.Timestamp = proto.Field(
        proto.MESSAGE,
        number=6,
        message=timestamp_pb2.Timestamp,
    )
    cvss_version: cvss.CVSSVersion = proto.Field(
        proto.ENUM,
        number=7,
        enum=cvss.CVSSVersion,
    )
    cvss_v2: cvss.CVSS = proto.Field(
        proto.MESSAGE,
        number=8,
        message=cvss.CVSS,
    )


class VulnerabilityOccurrence(proto.Message):
    r"""An occurrence of a severity vulnerability on a resource.

    Attributes:
        type_ (str):
            The type of package; whether native or non
            native (e.g., ruby gems, node.js packages,
            etc.).
        severity (grafeas.grafeas_v1.types.Severity):
            Output only. The note provider assigned
            severity of this vulnerability.
        cvss_score (float):
            Output only. The CVSS score of this
            vulnerability. CVSS score is on a scale of 0 -
            10 where 0 indicates low severity and 10
            indicates high severity.
        cvssv3 (grafeas.grafeas_v1.types.CVSS):
            The cvss v3 score for the vulnerability.
        package_issue (MutableSequence[grafeas.grafeas_v1.types.VulnerabilityOccurrence.PackageIssue]):
            Required. The set of affected locations and
            their fixes (if available) within the associated
            resource.
        short_description (str):
            Output only. A one sentence description of
            this vulnerability.
        long_description (str):
            Output only. A detailed description of this
            vulnerability.
        related_urls (MutableSequence[grafeas.grafeas_v1.types.RelatedUrl]):
            Output only. URLs related to this
            vulnerability.
        effective_severity (grafeas.grafeas_v1.types.Severity):
            The distro assigned severity for this
            vulnerability when it is available, otherwise
            this is the note provider assigned severity.

            When there are multiple PackageIssues for this
            vulnerability, they can have different effective
            severities because some might be provided by the
            distro while others are provided by the language
            ecosystem for a language pack. For this reason,
            it is advised to use the effective severity on
            the PackageIssue level. In the case where
            multiple PackageIssues have differing effective
            severities, this field should be the highest
            severity for any of the PackageIssues.
        fix_available (bool):
            Output only. Whether at least one of the
            affected packages has a fix available.
        cvss_version (grafeas.grafeas_v1.types.CVSSVersion):
            Output only. CVSS version used to populate cvss_score and
            severity.
        cvss_v2 (grafeas.grafeas_v1.types.CVSS):
            The cvss v2 score for the vulnerability.
        vex_assessment (grafeas.grafeas_v1.types.VulnerabilityOccurrence.VexAssessment):

        extra_details (str):
            Occurrence-specific extra details about the
            vulnerability.
    """

    class PackageIssue(proto.Message):
        r"""A detail for a distro and package this vulnerability
        occurrence was found in and its associated fix (if one is
        available).

        Attributes:
            affected_cpe_uri (str):
                Required. The `CPE
                URI <https://cpe.mitre.org/specification/>`__ this
                vulnerability was found in.
            affected_package (str):
                Required. The package this vulnerability was
                found in.
            affected_version (grafeas.grafeas_v1.types.Version):
                Required. The version of the package that is
                installed on the resource affected by this
                vulnerability.
            fixed_cpe_uri (str):
                The `CPE URI <https://cpe.mitre.org/specification/>`__ this
                vulnerability was fixed in. It is possible for this to be
                different from the affected_cpe_uri.
            fixed_package (str):
                The package this vulnerability was fixed in. It is possible
                for this to be different from the affected_package.
            fixed_version (grafeas.grafeas_v1.types.Version):
                Required. The version of the package this
                vulnerability was fixed in. Setting this to
                VersionKind.MAXIMUM means no fix is yet
                available.
            fix_available (bool):
                Output only. Whether a fix is available for
                this package.
            package_type (str):
                The type of package (e.g. OS, MAVEN, GO).
            effective_severity (grafeas.grafeas_v1.types.Severity):
                The distro or language system assigned
                severity for this vulnerability when that is
                available and note provider assigned severity
                when it is not available.
            file_location (MutableSequence[grafeas.grafeas_v1.types.FileLocation]):
                The location at which this package was found.
        """

        affected_cpe_uri: str = proto.Field(
            proto.STRING,
            number=1,
        )
        affected_package: str = proto.Field(
            proto.STRING,
            number=2,
        )
        affected_version: package.Version = proto.Field(
            proto.MESSAGE,
            number=3,
            message=package.Version,
        )
        fixed_cpe_uri: str = proto.Field(
            proto.STRING,
            number=4,
        )
        fixed_package: str = proto.Field(
            proto.STRING,
            number=5,
        )
        fixed_version: package.Version = proto.Field(
            proto.MESSAGE,
            number=6,
            message=package.Version,
        )
        fix_available: bool = proto.Field(
            proto.BOOL,
            number=7,
        )
        package_type: str = proto.Field(
            proto.STRING,
            number=8,
        )
        effective_severity: g_severity.Severity = proto.Field(
            proto.ENUM,
            number=9,
            enum=g_severity.Severity,
        )
        file_location: MutableSequence[common.FileLocation] = proto.RepeatedField(
            proto.MESSAGE,
            number=10,
            message=common.FileLocation,
        )

    class VexAssessment(proto.Message):
        r"""VexAssessment provides all publisher provided Vex information
        that is related to this vulnerability.

        Attributes:
            cve (str):
                Holds the MITRE standard Common Vulnerabilities and
                Exposures (CVE) tracking number for the vulnerability.
                Deprecated: Use vulnerability_id instead to denote CVEs.
            vulnerability_id (str):
                The vulnerability identifier for this
                Assessment. Will hold one of common identifiers
                e.g. CVE, GHSA etc.
            related_uris (MutableSequence[grafeas.grafeas_v1.types.RelatedUrl]):
                Holds a list of references associated with
                this vulnerability item and assessment.
            note_name (str):
                The VulnerabilityAssessment note from which this
                VexAssessment was generated. This will be of the form:
                ``projects/[PROJECT_ID]/notes/[NOTE_ID]``. (-- api-linter:
                core::0122::name-suffix=disabled aip.dev/not-precedent: The
                suffix is kept for consistency. --)
            state (grafeas.grafeas_v1.types.VulnerabilityAssessmentNote.Assessment.State):
                Provides the state of this Vulnerability
                assessment.
            impacts (MutableSequence[str]):
                Contains information about the impact of this
                vulnerability, this will change with time.
            remediations (MutableSequence[grafeas.grafeas_v1.types.VulnerabilityAssessmentNote.Assessment.Remediation]):
                Specifies details on how to handle (and
                presumably, fix) a vulnerability.
            justification (grafeas.grafeas_v1.types.VulnerabilityAssessmentNote.Assessment.Justification):
                Justification provides the justification when the state of
                the assessment if NOT_AFFECTED.
        """

        cve: str = proto.Field(
            proto.STRING,
            number=1,
        )
        vulnerability_id: str = proto.Field(
            proto.STRING,
            number=8,
        )
        related_uris: MutableSequence[common.RelatedUrl] = proto.RepeatedField(
            proto.MESSAGE,
            number=2,
            message=common.RelatedUrl,
        )
        note_name: str = proto.Field(
            proto.STRING,
            number=3,
        )
        state: vex.VulnerabilityAssessmentNote.Assessment.State = proto.Field(
            proto.ENUM,
            number=4,
            enum=vex.VulnerabilityAssessmentNote.Assessment.State,
        )
        impacts: MutableSequence[str] = proto.RepeatedField(
            proto.STRING,
            number=5,
        )
        remediations: MutableSequence[
            vex.VulnerabilityAssessmentNote.Assessment.Remediation
        ] = proto.RepeatedField(
            proto.MESSAGE,
            number=6,
            message=vex.VulnerabilityAssessmentNote.Assessment.Remediation,
        )
        justification: vex.VulnerabilityAssessmentNote.Assessment.Justification = (
            proto.Field(
                proto.MESSAGE,
                number=7,
                message=vex.VulnerabilityAssessmentNote.Assessment.Justification,
            )
        )

    type_: str = proto.Field(
        proto.STRING,
        number=1,
    )
    severity: g_severity.Severity = proto.Field(
        proto.ENUM,
        number=2,
        enum=g_severity.Severity,
    )
    cvss_score: float = proto.Field(
        proto.FLOAT,
        number=3,
    )
    cvssv3: cvss.CVSS = proto.Field(
        proto.MESSAGE,
        number=10,
        message=cvss.CVSS,
    )
    package_issue: MutableSequence[PackageIssue] = proto.RepeatedField(
        proto.MESSAGE,
        number=4,
        message=PackageIssue,
    )
    short_description: str = proto.Field(
        proto.STRING,
        number=5,
    )
    long_description: str = proto.Field(
        proto.STRING,
        number=6,
    )
    related_urls: MutableSequence[common.RelatedUrl] = proto.RepeatedField(
        proto.MESSAGE,
        number=7,
        message=common.RelatedUrl,
    )
    effective_severity: g_severity.Severity = proto.Field(
        proto.ENUM,
        number=8,
        enum=g_severity.Severity,
    )
    fix_available: bool = proto.Field(
        proto.BOOL,
        number=9,
    )
    cvss_version: cvss.CVSSVersion = proto.Field(
        proto.ENUM,
        number=11,
        enum=cvss.CVSSVersion,
    )
    cvss_v2: cvss.CVSS = proto.Field(
        proto.MESSAGE,
        number=12,
        message=cvss.CVSS,
    )
    vex_assessment: VexAssessment = proto.Field(
        proto.MESSAGE,
        number=13,
        message=VexAssessment,
    )
    extra_details: str = proto.Field(
        proto.STRING,
        number=14,
    )


__all__ = tuple(sorted(__protobuf__.manifest))
